﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using System.Windows;

using System.IO;
using System.Data;
using System.Windows.Forms;
using System.Windows.Controls;
using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;
using NPOI.SS.Util;
using NPOI.SS.UserModel;
using NPOI.HSSF.Util;

namespace CSSAdriverapp
{
    /// <summary>
    /// Interaction logic for DriverMain.xaml
    /// </summary>
    public partial class DriverMain : Window
    {
        int count = new int();
        BackgroundWorker worker = new BackgroundWorker();
        List<DateTime> dates = new List<DateTime>();
        List<MainGrid> me = new List<MainGrid>();
        DateTime date = DateTime.Now;
        DataTable driverMainSchedule = new DataTable();  //creates data table
        System.Windows.Forms.MessageBox message3;
        string text;
        public DriverMain()
        {
            InitializeComponent();
        }


        public List<MainGrid> mainEvents
        {
            get;
            set;
        }
       

        private List<Event> getEvents()
        {
            DataClassesDataContext db = new DataClassesDataContext();

            IQueryable<Event> tevents = from c in db.Events where dates.Contains(c.Date) select c;

            return tevents.ToList();
        }

        private List<Driver> getDrivers()
        {
            DataClassesDataContext db = new DataClassesDataContext();

            IQueryable<Driver> tdrivers = from c in db.Drivers select c;

            return tdrivers.ToList();
        }

        private List<Vehicle> getVehicles()
        {
            DataClassesDataContext db = new DataClassesDataContext();

            IQueryable<Vehicle> tvehicles = from c in db.Vehicles select c;

            return tvehicles.ToList();
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            populateGrid();
        }

        private void StartWork()
        {

            progressBar.Visibility = System.Windows.Visibility.Visible;
            progressBar.Value = 0;
            worker.DoWork += DoWork;
            worker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            worker.WorkerReportsProgress = true;
            worker.RunWorkerCompleted += WorkerCompleted;
            worker.RunWorkerAsync();
            
            
        }

        private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //Hide your wait dialog
            progressBar.Visibility = System.Windows.Visibility.Hidden;
            displayDataGrid.ItemsSource = me;
            rectangle.Visibility = System.Windows.Visibility.Hidden; 
        }

        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // The progress percentage is a property of e
            progressBar.Maximum = count;
            progressBar.Value++;
        }

        private void populateGrid()
        {
           
            try
            {
                DataClassesDataContext db = new DataClassesDataContext();

                List<Event> events = getEvents();
                List<Driver> drivers = getDrivers();
                List<Vehicle> vehicles = getVehicles();
                count = events.Count();
                List<MainGrid> mainEvents = new List<MainGrid>();

                foreach (Event e in events)
                {
                   
                    COMSERV_ACTIVITY a = ((COMSERV_ACTIVITY)(from b in db.COMSERV_ACTIVITies where b.activityid == e.ServiceID select b).FirstOrDefault());

                    MainGrid mainevent = new MainGrid();
                    mainevent.eventid = e.ID;
                    mainevent.date = e.Date;
                    mainevent.drivetime = (int)a.travel_time;
                    mainevent.depart = ((DateTime)a.begin_time).AddMinutes(-(int)a.travel_time);
                    Console.WriteLine(mainevent.depart.ToString("hh:mm"));
                    mainevent.returntime = ((DateTime)a.end_time).AddMinutes((int)a.travel_time);
                    mainevent.servicetimebegin = ((DateTime)a.begin_time);
                    mainevent.servicetimeend = ((DateTime)a.end_time);
                    Driver d = ((Driver)(from c in drivers where c.ID == e.DriverID select c).FirstOrDefault());
                    if (d == null)
                    {
                        mainevent.driver = "      ";
                    }
                    else
                    {
                        mainevent.driver = d.first_name + " " + d.last_name;
                    }            
                    Vehicle v = ((Vehicle)(from c in vehicles where c.ID == e.VehicleID select c).FirstOrDefault());
                    if (v == null)
                    {
                        mainevent.transportation = "      ";
                    }
                    else
                    {
                        mainevent.transportation = v.Name;
                    }
                    mainevent.site = a.activity_name;
                    mainevent.numattending = (int)a.maxstu;
                    mainevent.Notes = e.Notes;
                    mainevent.ActivityComments = e.Activity_Comments;
                    mainEvents.Add(mainevent);

                    worker.ReportProgress(1);
                }

                me = mainEvents;
                driverMainSchedule.Clear();
                driverMainSchedule.Columns.Clear();
                driverMainSchedule.Columns.Add("Date");   //creates columns in datatable DriverMainSchedule with with headers. 
                driverMainSchedule.Columns.Add("Departure Time");
                driverMainSchedule.Columns.Add("Arrival Time");
                driverMainSchedule.Columns.Add("Driver");
                driverMainSchedule.Columns.Add("Vehicle");
                driverMainSchedule.Columns.Add("Service Start");
                driverMainSchedule.Columns.Add("Service End");
                driverMainSchedule.Columns.Add("Site");
                driverMainSchedule.Columns.Add("# Attending");
                driverMainSchedule.Columns.Add("Notes");
                driverMainSchedule.Columns.Add("Comments");
                for (int i = 0; i <= me.Count - 1; i++)   //fills rows in datatable with mainEvent data attached to the datagrid.
                {
                    DataRow dm = driverMainSchedule.NewRow();
                    dm[0] = me[i].date.ToString("dddd, MMMM d, yyyy");
                    dm[1] = me[i].depart.ToString("h:mm tt");
                    dm[2] = me[i].returntime.ToString("h:mm tt");
                    dm[3] = me[i].driver;
                    dm[4] = me[i].transportation;
                    dm[5] = me[i].servicetimebegin.ToString("h:mm tt");
                    dm[6] = me[i].servicetimeend.ToString("h:mm tt");
                    dm[7] = me[i].site;
                    dm[8] = me[i].numattending;
                    dm[9] = me[i].Notes;
                    dm[10] = me[i].ActivityComments;
                    driverMainSchedule.Rows.Add(dm);
                }
                displayDataGrid.ItemsSource = me;
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

        }

        private void Add_Driver_Click(object sender, RoutedEventArgs e)
        {
            AddDriver openup = new AddDriver();
            openup.Show();
        }

        private void Edit_Driver_Click(object sender, RoutedEventArgs e)
        {
            EditDriver openup = new EditDriver();
            openup.Show();
        }

        private void Add_Vehicle_Type_Click(object sender, RoutedEventArgs e)
        {
            AddVehicleType openup = new AddVehicleType();
            openup.Show();
        }

        private void Edit_Vehicle_Type_Click(object sender, RoutedEventArgs e)
        {
            EditVehicleType openup = new EditVehicleType();
            openup.Show();
        }

        private void Add_Vehicle_Click(object sender, RoutedEventArgs e)
        {
            AddVehicle openup = new AddVehicle();
            openup.Show();
        }

        private void Edit_Vehicle_Click(object sender, RoutedEventArgs e)
        {
            EditVehicle openup = new EditVehicle();
            openup.Show();
        }

        private void Generate_Events_Click(object sender, RoutedEventArgs e)
        {
            GenerateEvents openup = new GenerateEvents();
            openup.Show();
        }

        private void Schedule_Transportation_Click(object sender, RoutedEventArgs e)
        {
            ScheduleTransportation openup = new ScheduleTransportation();
            openup.Show();
        }


        private void About_Click(object sender, RoutedEventArgs e)
        {
            AboutBox openup = new AboutBox();
            openup.Show();
        }

        
        private void Export_Excel_Click(object sender, RoutedEventArgs e)
        {
       
            if (displayDataGrid.Items.Count == 0)
            {
                string text = "Datagrid is empty. Please select a date to export.";
                string caption = "Cannot Export";
                MessageBoxResult message3 = System.Windows.MessageBox.Show(text, caption, MessageBoxButton.OK, MessageBoxImage.Information);
                
            }
            else
            {

            //  Displays a SaveFileDialog 
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.FileName = "DriverApp Export " + (calendar.SelectedDates.First().ToString("MMMM d, yyyy"));
            saveFileDialog1.Filter = "Excel Worksheets (*.xls, *.xlsx)|*.xls;*.xlsx";
            saveFileDialog1.Title = "Save an Excel File";
            saveFileDialog1.ShowDialog();
            

            // If the file name is not an empty string open it for saving.
            if (saveFileDialog1.FileName != "")
            {
                    try
                    {
                        //Saves FileStream created by the OpenFile method.
                        System.IO.FileStream fs = (System.IO.FileStream)saveFileDialog1.OpenFile();
                         fs.Close();
                    }
                    catch (Exception ex)
                    {
                        string Message = "The file you are trying to save over is open in another process. Please close the file or save in a different name.";
                        string questionCaption = "File Open in Another Process";
                        MessageBoxResult message3 = System.Windows.MessageBox.Show(Message, questionCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                }

            if (saveFileDialog1.FileName != "")
            {
                DataColumnCollection dc = driverMainSchedule.Columns;
                try
                {
                        using (FileStream stream = new FileStream(saveFileDialog1.FileName, FileMode.Create, FileAccess.Write)) //creates an xls files and writes it to the location of the file
                    {
                        HSSFWorkbook workbook = new HSSFWorkbook(); //creates an excel workbook
                        ISheet sheet1 = workbook.CreateSheet("Sheet1"); //creates an excel sheet
                        NPOI.SS.UserModel.IFont font = workbook.CreateFont();
                        font.Boldweight = (short)FontBoldWeight.Bold;
                        ICellStyle style1 = workbook.CreateCellStyle();
                        style1.SetFont(font);
                        for (int i = 0; i < driverMainSchedule.Rows.Count + 1; i++)
                        {
                            IRow row = sheet1.CreateRow(i); //class within NPOI that references rows
                            for (int j = 0; j < driverMainSchedule.Columns.Count; j++)
                            {
                                ICell cell = row.CreateCell(j); //class within NPOI that references cells within excel
                                if (i == 0)
                                {
                                    cell.SetCellValue(dc[j].ToString()); //if the first row is located, then adds columns from DataColumnCollection.
                                    cell.CellStyle = style1;
                                }
                                else
                                {
                                    cell.SetCellValue(driverMainSchedule.Rows[i - 1].ItemArray[j].ToString());
                                }
                                sheet1.AutoSizeColumn(i);
                                sheet1.AutoSizeColumn(j);
                            }
                        }
                        workbook.Write(stream); //writes data to stream
                    }
                    driverMainSchedule.AcceptChanges();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
                }
            }
        }

        private void Close_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void Schedule_Weekly_Transportation_Click(object sender, RoutedEventArgs e)
        {
            WeeklyVanScheduler openup = new WeeklyVanScheduler();
            openup.Show();
        }

        private void Update_Events_Click(object sender, RoutedEventArgs e)
        {
            UpdateEvents openup = new UpdateEvents();
            openup.Show();
        }

        private void Assign_Driver_Click(object sender, RoutedEventArgs e)
        {
            AssignDriver openup = new AssignDriver();
            openup.Show();
        }

        private void Driver_Info_Click(object sender, RoutedEventArgs e)
        {
            DriverInfo openup = new DriverInfo();
            openup.Show();
        }

        private void Available_Drivers(object sender, RoutedEventArgs e)
        {
            AvailableDrivers openup = new AvailableDrivers();
            openup.Show();
        }

        private void Activity_Update_Click(object sender, RoutedEventArgs e)
        {
            UpdateActivity openup = new UpdateActivity();
            openup.Show();
        }

        private void Edit_Notes_Click(object sender, RoutedEventArgs e)
        {
            MainGrid obj = displayDataGrid.SelectedItem as MainGrid;
            EditNotes openup = new EditNotes(obj.eventid);
            openup.Show();
        }

        private void Activity_Comments_Click(object sender, RoutedEventArgs e)
        {
            EditActivityComments openup = new EditActivityComments();
            openup.Show();
        }

        /// <summary>
        /// Deletes driver schedule information notifying the user through a messagebox before calling the cleardriverschedules method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Activity_ClearDriverSchedules_Click(object sender, RoutedEventArgs e)
        {
            
            string questionMessage = "Are you sure you want to clear driver schedule data?";
            string questionCaption = "Confirmation";
            MessageBoxResult questionConfirmation = System.Windows.MessageBox.Show(questionMessage, questionCaption, MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (questionConfirmation == MessageBoxResult.Yes)
            {
                ClearDriverSchedules();
            }
        }
        /// <summary>
        /// Uses a Link database class to pull information from driver availabilities table and then it deletes it
        /// </summary>
        private void ClearDriverSchedules()
        {
            try
            {
                DataClassesDataContext db = new DataClassesDataContext();
                // Query the database for the rows to be deleted.
                var deletePreferences =
                    from preferences in db.driver_availabilities
                    select preferences;

                foreach (var preference in deletePreferences)
                {
                    db.driver_availabilities.DeleteOnSubmit(preference);
                }

                try
                {
                    db.SubmitChanges();
                    string resultsMessage = "Driver Schedules have been removed";
                    string resultsCaption = "Update Completed";
                    MessageBoxResult finishedResult = System.Windows.MessageBox.Show(resultsMessage, resultsCaption, MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception c)
                {
                    string errorMessage = "An error has occured during the driver schedules update";
                    string errorCaption = "Error during update";
                    MessageBoxResult finishedResult = System.Windows.MessageBox.Show(errorMessage, errorCaption, MessageBoxButton.OK, MessageBoxImage.Error);
                    Console.WriteLine(c);
                    // Provide for exceptions.
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }


        private void calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
           
            rectangle.Visibility = System.Windows.Visibility.Visible; 
            dates = calendar.SelectedDates.ToList();

       
            if (dates.Count() > 0)
            {
                calendarExpander.Header = calendar.SelectedDates.First().ToString("MMM d") + " - " + calendar.SelectedDates.Last().ToString("MMM d"); 
                StartWork();
                
               
            }
        }


        private void Edit_EventVehicle_Click(object sender, RoutedEventArgs e)
        {
            MainGrid obj = displayDataGrid.SelectedItem as MainGrid;
            EditEventVehicle openup = new EditEventVehicle(obj.eventid);
            openup.Show();
        }

       
     


    }
}
